package com.itcat.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itcat.api.mysql.*;
import com.itcat.common.CommonPage;
import com.itcat.common.ResultCode;
import com.itcat.exception.BusinessException;
import com.itcat.interceptor.UserHolder;
import com.itcat.mysql.param.UmsAdminParam;
import com.itcat.mysql.param.UpdatePasswordParam;
import com.itcat.mysql.pojo.*;
import com.itcat.service.AdminCacheService;
import com.itcat.service.TimeLineService;
import com.itcat.service.UmsAdminService;
import com.itcat.utils.JwtUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * [一句话描述该类的功能]
 *
 * @author : [Cr Mr]
 * @version : [v1.0]
 * @date : [2022/3/30 14:41]
 */
@Service
public class UmsAdminServiceImpl implements UmsAdminService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);

    @Autowired
    private AdminCacheService adminCacheService;

    @Autowired
    private TimeLineService timeLineService;


    @Override
    public String login(String username, String password) {
        String token = null;
        Md5Hash md5Hash = new Md5Hash(password);
        String hex = md5Hash.toHex();
        UmsAdmin umsAdmin = umsAdminApi.selectLogin(username);
        if (umsAdmin.getPassword().equals(hex)) {
            Map tokenMap = new HashMap();
            tokenMap.put("id", umsAdmin.getId());
            tokenMap.put("username", username);
            token = JwtUtils.getToken(tokenMap);
        }
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String remoteAddr = request.getRemoteAddr();
        timeLineService.saveLoginTime(umsAdmin.getId());
        timeLineService.insertLoginLog(umsAdmin, remoteAddr);
        return token;
    }

    @DubboReference
    private UmsAdminApi umsAdminApi;

    /***
     * 通过用户名获取管理员
     * @author Cr Mr
     * @date 2022/3/30 18:33
     */
    @Override
    public UmsAdmin getAdminByUsername(String username) {
        //从管理员缓存服务获取admin
        UmsAdmin admin = adminCacheService.getAdmin(username);
        if (admin != null) {
            return admin;
        }
        admin = umsAdminApi.selectByName(username);
        if (admin != null) {
            adminCacheService.setAdmin(admin);
            return admin;
        }
        return null;
    }

    @DubboReference
    private UmsAdminRoleRelationApi umsAdminRoleRelationApi;

    /***
     * 获取用户所有可访问资源
     * @author Cr Mr
     * @date 2022/3/31 18:45
     */
    @Override
    public List<UmsResource> getResourceList(Long adminId) {
        List<UmsResource> resourceList = adminCacheService.getResourceList(adminId);
        if (CollUtil.isNotEmpty(resourceList)) {
            return resourceList;
        }
        resourceList = umsAdminRoleRelationApi.getResourceList(adminId);
        if (CollUtil.isNotEmpty(resourceList)) {
            adminCacheService.setResourceList(adminId, resourceList);
        }
        return resourceList;
    }

    @DubboReference
    private UmsAdminRoleApi umsAdminRoleApi;

    @DubboReference
    private UmsMenuApi umsMenuApi;


    /***
     * 获取当前登录用户信息
     * @author Cr Mr
     * @date 2022/4/1 22:21
     */
    @Override
    public Map info(String username) {
        UmsAdmin umsAdmin = getAdminByUsername(username);
        HashMap<String, Object> map = new HashMap<>();
        map.put("icon", umsAdmin.getIcon());
        map.put("username", umsAdmin.getUsername());
        Long userId = UserHolder.getUserId();
        List<UmsRole> umsRole = umsAdminRoleApi.getUmsRole(userId);
        String roleName = "";
        for (UmsRole role : umsRole) {
            roleName = roleName + role.getName();
        }
        ArrayList<String> list = new ArrayList<>();
        list.add(roleName);
        map.put("roles", list);
        List<Long> ids = CollUtil.getFieldValues(umsRole, "id", Long.class);
        List<UmsMenu> menuList = umsMenuApi.getMenuList(ids);
        map.put("menus", menuList);
        return map;
    }

    /***
     * 刷新token
     * @author Cr Mr
     * @date 2022/4/2 10:00
     */
    @Override
    public String refreshToken() {
        Map tokenMap = new HashMap();
        tokenMap.put("id", UserHolder.getUserId());
        UmsAdmin umsAdmin = umsAdminApi.selectById(UserHolder.getUserId());
        tokenMap.put("username", umsAdmin.getUsername());
        String token = JwtUtils.getToken(tokenMap);
        return token;
    }

    /***
     * 根据用户名或姓名分页获取用户列表
     * @author Cr Mr
     * @date 2022/4/2 12:16
     */
    @Override
    public CommonPage<UmsAdmin> getPage(String username, Integer pageNum, Integer pageSize) {
        Page<UmsAdmin> selectPage = umsAdminApi.selectPage(username, pageNum, pageSize);
        CommonPage<UmsAdmin> page = CommonPage.restPage(selectPage);
        return page;
    }

    @Override
    public void delete(Long id) {
        umsAdminApi.delete(id);
    }

    @Override
    public void reoleUpdate(Long adminId, Long[] roleIds) {
        umsAdminApi.insertReoles(adminId, roleIds);
    }

    /***
     * 获取指定用户的角色
     * @author Cr Mr
     * @date 2022/4/2 19:14
     */
    @Override
    public List<UmsRole> getByRole(Long adminId) {
        List<UmsRole> list = umsAdminRoleApi.getUmsRole(adminId);
        return list;
    }

    /***
     * 修改指定用户信息
     * @author Cr Mr
     * @date 2022/4/2 19:33
     */
    @Override
    public void update(UmsAdmin admin) {
        adminCacheService.removeAdmin(UserHolder.get());
        Md5Hash md5Hash = new Md5Hash(admin.getPassword());
        admin.setPassword(md5Hash.toHex());
        umsAdminApi.update(admin);
    }

    /***
     * 修改指定用户密码
     * @author Cr Mr
     * @date 2022/4/2 19:45
     */
    @Override
    public void updatePassword(UpdatePasswordParam updatePasswordParam) {
        UmsAdmin umsAdmin = umsAdminApi.selectByName(updatePasswordParam.getUsername());
        adminCacheService.removeAdmin(UserHolder.get());
        Md5Hash md5Hash = new Md5Hash(updatePasswordParam.getOldPassword());
        String hex = md5Hash.toHex();
        if (!umsAdmin.getPassword().equals(hex)) {
            throw  new BusinessException(ResultCode.LOGIN_FAILED);
        }
        Md5Hash md5Hash1 = new Md5Hash(updatePasswordParam.getNewPassword());
        String password = md5Hash1.toHex();
        umsAdminApi.updatePassword(updatePasswordParam.getUsername(), password);
    }

    /***
     * 修改帐号状态
     * @author Cr Mr
     * @date 2022/4/2 20:58
     */
    @Override
    public void updateStatus(Long id, Integer status) {
        UmsAdmin umsAdmin = umsAdminApi.selectById(id);
        adminCacheService.removeAdmin(umsAdmin);
        umsAdminApi.updateStatus(id, status);
    }

    /***
     * 获取指定用户信息
     * @author Cr Mr
     * @date 2022/4/2 21:13
     */
    @Override
    public UmsAdmin getUmsAdmin(Long id) {
        UmsAdmin umsAdmin = umsAdminApi.selectById(id);
        return umsAdmin;
    }

    /***
     * 用户注册
     * @author Cr Mr
     * @date 2022/4/2 22:33
     */
    @Override
    public UmsAdmin register(UmsAdminParam umsAdminParam) {
        UmsAdmin umsAdmin = new UmsAdmin();
        BeanUtils.copyProperties(umsAdminParam, umsAdmin);
        Md5Hash md5Hash = new Md5Hash(umsAdmin.getPassword());
        String password = md5Hash.toHex();
        umsAdmin.setPassword(password);
        umsAdminApi.insert(umsAdmin);
        return umsAdmin;
    }


}
